package com.hyt.it.ogt.kq.service.gov.arrange;

import com.hyt.it.ogt.kq.common.config.exception.KqException;
import com.hyt.it.ogt.kq.common.gov.constant.ResponseCode;
import com.hyt.it.ogt.kq.common.gov.enums.ProctorArrangeParamEnum;
import com.hyt.it.ogt.kq.service.gov.arrange.model.Proctor;
import com.hyt.it.ogt.kq.service.gov.arrange.model.Room;
import com.hyt.it.ogt.kq.service.gov.model.entity.TimeExaminer;
import com.hyt.it.ogt.kq.service.gov.model.entity.TimeRoomExaminer;
import com.hyt.it.ogt.kq.service.gov.model.param.proctor.AutoProctorParam;
import com.hyt.loginfo.model.Organization;
import com.hyt.progress.service.ProgressManager;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedDeque;


@Service
public class ProctorArrangeByOfficeAdapter extends ProctorArrangeAbstractService {

    @Override
    public void arrange(AutoProctorParam param) {
        ProgressManager.updateProgress(5L);
        // 要编排的机构层级
        int level = this.getLevel(param, ProctorArrangeParamEnum.ARRANGE_OFFICE_LEVEL);
        // 要编排的监考老师数量
        int teacherNum = this.getTeacherNum(param);
        ProgressManager.updateProgress(15L);

        Map<String, Organization> orgMap = new HashMap<>();

        // 把监考员按照级别分类好，已过滤不符合编排级别的监考员
        Map<String, ConcurrentLinkedDeque<Proctor>> proctorMap = this.getProctorList(param.getTaskId(), level, orgMap);
        ProgressManager.updateProgress(35L);

        if (proctorMap.isEmpty()) {
            throw new KqException(ResponseCode.PROCTOR_ARRANGE_NOT_MATCH.getCode(), ResponseCode.PROCTOR_ARRANGE_NOT_MATCH.getMsg());
        }

        // 获取所有考场
        List<Room> dataList = timeRoomCandidateMapper.getProctorArrangeRoomList(param.getTaskId());
        ProgressManager.updateProgress(55L);

        Map<String, TimeExaminer> timeExaminerMap = new HashMap<>();
        List<TimeRoomExaminer> timeRoomExaminerList = new ArrayList<>();

        for (Room e : dataList) {
            // 先拿到考场的级别
            Organization dept = orgMap.get(e.getDept());
            if (dept == null) {
                // 查询上级部门
                dept = iUaDeptService.getDeptById(e.getDept());
                orgMap.put(e.getDept(), dept);
            }
            if (dept == null) {
                continue;
            }
            String[] split = dept.getAncestors().split(",");

            String key = null;
            // 根据级别构造key，需要符合监考员的构造方式
            if (split.length >= level) {
                key = split[level - 1];
            } else {
                continue;
            }

            // 拿到同级别的监考员列表
            ConcurrentLinkedDeque<Proctor> proctors = proctorMap.get(key);
            // 判空null，没有，则该考场跳过不编排
            if (CollectionUtils.isEmpty(proctors)) {
                continue;
            }

            // 把监考员编进考场，构造表数据对象
            this.buildData(param, teacherNum, timeExaminerMap, timeRoomExaminerList, e, proctors);
        }
        ProgressManager.updateProgress(95L);
        if (timeRoomExaminerList.size() > 0) {
            iTimeRoomExaminerService.saveBatch(timeRoomExaminerList);
            iTimeExaminerService.saveBatch(timeExaminerMap.values());
            ProgressManager.updateProgress(98L);
        } else {
            throw new KqException(ResponseCode.PROCTOR_ARRANGE_NOT_MATCH.getCode(), ResponseCode.PROCTOR_ARRANGE_NOT_MATCH.getMsg());
        }
    }

    /**
     * 把监考员按要编排的级别分组
     * @param taskId
     * @param level
     * @param orgMap
     * @return
     */
    private Map<String, ConcurrentLinkedDeque<Proctor>> getProctorList(String taskId, int level, Map<String, Organization> orgMap) {
        Map<String, ConcurrentLinkedDeque<Proctor>> map = new HashMap<>();
        // 先查询所有监考员
        List<Proctor> dataList = examinerMapper.getProctorList(taskId);
        for (Proctor p : dataList) {
            // 获取监考员属于第几级
            String key = null;
            Organization dept = orgMap.get(p.getDept());
            if (dept == null) {
                dept = iUaDeptService.getDeptById(p.getDept());
                orgMap.put(p.getDept(), dept);
            }
            String[] split = dept.getAncestors().split(",");
            if (split.length >= level) {
                key = split[level - 1];
            } else {
                // 小于要编排的监考员，过滤掉
                continue;
            }

            // 符合，则存储该监考员到这一组中
            ConcurrentLinkedDeque<Proctor> list = map.get(key);
            if (list == null) {
                list = new ConcurrentLinkedDeque<>();
                map.put(key, list);
            }
            list.add(p);
        }
        return map;
    }

}
